package com.ai.module.mj.helper;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.text.CharSequenceUtil;
import com.ai.module.mj.config.propertites.YmlProperties;
import com.ai.module.mj.constant.enums.TaskStatus;
import com.ai.module.mj.constant.stringConstant.ReturnCode;
import com.ai.module.mj.domain.DiscordAccount;
import com.ai.module.mj.domain.Task;
import com.ai.module.mj.loadbalancer.DiscordInstance;
import com.ai.module.mj.loadbalancer.DiscordLoadBalancer;
import com.ai.module.mj.util.AsyncLockUtils;
import com.ai.module.mj.util.SnowFlakeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Component
@Order(Integer.MIN_VALUE)
@RequiredArgsConstructor
public class DiscordAccountInitializer implements ApplicationRunner {
	private final DiscordLoadBalancer discordLoadBalancer;
	private final DiscordAccountHelper discordAccountHelper;
	private final YmlProperties properties;

	@Override
	public void run(ApplicationArguments args) throws Exception {
		YmlProperties.ProxyConfig proxy = this.properties.getProxy();
		if (Strings.isNotBlank(proxy.getHost())) {
			System.setProperty("http.proxyHost", proxy.getHost());
			System.setProperty("http.proxyPort", String.valueOf(proxy.getPort()));
			System.setProperty("https.proxyHost", proxy.getHost());
			System.setProperty("https.proxyPort", String.valueOf(proxy.getPort()));
		}

		List<YmlProperties.DiscordAccountConfig> configAccounts = this.properties.getAccounts();
		if (CharSequenceUtil.isNotBlank(this.properties.getDiscord().getChannelId())) {
			configAccounts.add(this.properties.getDiscord());
		}
		List<DiscordInstance> instances = this.discordLoadBalancer.getAllInstances();
		for (YmlProperties.DiscordAccountConfig configAccount : configAccounts) {
			DiscordAccount account = new DiscordAccount();
			BeanUtil.copyProperties(configAccount, account);
			account.setId(configAccount.getChannelId());
			try {
				DiscordInstance instance = this.discordAccountHelper.createDiscordInstance(account);
				if (!account.isEnable()) {
					continue;
				}
				instance.startWss();
				AsyncLockUtils.LockObject lock = AsyncLockUtils.waitForLock("wss:" + account.getChannelId(), Duration.ofSeconds(10));
				if (ReturnCode.SUCCESS != lock.getProperty("code", Integer.class, 0)) {
					throw new ValidateException(lock.getProperty("description", String.class));
				}
//				testTask(instance);
				instances.add(instance);
			} catch (Exception e) {
				e.printStackTrace();
				log.error("Account({}) init fail, disabled: {}", account.getDisplay(), e.getMessage());
				account.setEnable(false);
			}
		}
		Set<String> enableInstanceIds = instances.stream().filter(DiscordInstance::isAlive).map(DiscordInstance::getInstanceId).collect(Collectors.toSet());
		log.info("当前可用账号数 [{}] - {}", enableInstanceIds.size(), String.join(", ", enableInstanceIds));
		//

	}

	@Deprecated
	private static void testTask(DiscordInstance instance) {
		List<Task> runningTasks = instance.getRunningTasks();
		Task task = new Task();
		Task task1 = new Task();
		Task task2 = new Task();
		task.setProgress("15%");
		task.setId(SnowFlakeUtil.INSTANCE.nextId());
		task.setStatus(TaskStatus.SUCCESS);
		task.setRobotId("loadCookie-robot");
		BeanUtils.copyProperties(task,task1);
		BeanUtils.copyProperties(task,task2);
		task2.setStatus(TaskStatus.SUBMITTED);
		task1.setStatus(TaskStatus.IN_PROGRESS);
		runningTasks.add(task);
		runningTasks.add(task1);
		runningTasks.add(task2);
	}

}
